package ucl.cs.stockBroker.server;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import ucl.cs.stockBroker.common.StockBroker;

public class ServerReader implements Runnable {

	private StockBroker stockBroker;

	public ServerReader(StockBrokerImpl stockBroker) {
		this.stockBroker = stockBroker;
	}

	public void run() {
		try {
			loadAccounts();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
	}

	private void loadAccounts() {
		try {
			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
			Document doc = docBuilder.parse(new File("data/info.xml"));
			// normalise text representation
			doc.getDocumentElement().normalize();

			String name = null;
			String pin = null;
			String symbol = null;
			int quantity = 0;
			float balance = 0.0f;
			Map<String, Integer> shares = new HashMap<String, Integer>();

			NodeList listOfAccounts = doc.getElementsByTagName("account");
			for (int i = 0; i < listOfAccounts.getLength(); i++) {

				Node firstAccountNode = listOfAccounts.item(i);

				if (firstAccountNode.getNodeType() == Node.ELEMENT_NODE) {

					Element firstAccountElement = (Element) firstAccountNode;

					// -------
					NodeList nameList = firstAccountElement
							.getElementsByTagName("name");
					Element nameElement = (Element) nameList.item(0);

					NodeList textNameList = nameElement.getChildNodes();
					name = ((Node) textNameList.item(0)).getNodeValue().trim();

					// -------
					NodeList pinList = firstAccountElement
							.getElementsByTagName("pin");
					Element pinElement = (Element) pinList.item(0);

					NodeList textPinList = pinElement.getChildNodes();
					pin = PINCipher.decryptPin(((Node) textPinList.item(0))
							.getNodeValue().trim());

					// -------
					NodeList balanceList = firstAccountElement
							.getElementsByTagName("balance");
					Element balanceElement = (Element) balanceList.item(0);

					NodeList textBalanceList = balanceElement.getChildNodes();
					balance = Float.valueOf(((Node) textBalanceList.item(0))
							.getNodeValue().trim());

					// -------
					NodeList listOfShares = firstAccountNode.getChildNodes();
					Map<String, Integer> tempShares = new HashMap<String, Integer>();
					for (int j = 0; j < listOfShares.getLength(); j++) {
						Node firstShareNode = listOfShares.item(j);

						if (firstShareNode.getNodeType() == Node.ELEMENT_NODE
								&& firstShareNode.getNodeName().equals("share")) {

							Element firstShareElement = (Element) firstShareNode;

							// --------
							NodeList symbolList = firstShareElement
									.getElementsByTagName("symbol");
							Element symbolElement = (Element) symbolList
									.item(0);

							NodeList textSymbolList = symbolElement
									.getChildNodes();
							symbol = ((Node) textSymbolList.item(0))
									.getNodeValue().trim();

							// --------
							NodeList quantityList = firstShareElement
									.getElementsByTagName("quantity");
							Element quantityElement = (Element) quantityList
									.item(0);

							NodeList textQuantityList = quantityElement
									.getChildNodes();
							quantity = Integer.valueOf(((Node) textQuantityList
									.item(0)).getNodeValue().trim());
							tempShares.put(symbol, quantity);
						}

					}
					shares = tempShares;
					stockBroker.internalCreateAccount(name, pin, balance,
							shares);

				}
			}
		} catch (FileNotFoundException e) {
			new File("data/info.xml");
		} catch (SAXException e) {
			// e.printStackTrace();
		} catch (IOException e) {
			// e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// e.printStackTrace();
		}
	}
}
